package com.xingfei.blog.service.impl;

import com.alibaba.fastjson.JSON;
import com.xingfei.blog.baseMapper.UserInfoMapper;
import com.xingfei.blog.baseMapper.UserMapper;
import com.xingfei.blog.constants.ErrorConstants;
import com.xingfei.blog.constants.GeneralConstants;
import com.xingfei.blog.dto.UserDTO;
import com.xingfei.blog.dto.UserInfoDTO;
import com.xingfei.blog.mapper.UserDOExtMapper;
import com.xingfei.blog.mapper.UserDOMapper;
import com.xingfei.blog.mapper.UserInfoDOExtMapper;
import com.xingfei.blog.model.UserDO;
import com.xingfei.blog.model.UserInfoDO;
import com.xingfei.blog.model.UserInfoDOExample;
import com.xingfei.blog.redisCluster.RedisClusterUtil;
import com.xingfei.blog.result.ResultConstructor;
import com.xingfei.blog.result.ServiceResult;
import com.xingfei.blog.service.BlogUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;

/**
 * Created by xingfei on 2017/1/16.
 */
@Service("blogUserService")
public class BlogUserServiceImpl implements BlogUserService {
    @Autowired
    private UserDOMapper userDOMapper;
    @Autowired
    private UserDOExtMapper userDOExtMapper;
    @Autowired
    private UserInfoDOExtMapper userInfoDOExtMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private RedisClusterUtil redisCluster;
    //日志
    private static Logger logger = LoggerFactory.getLogger(BlogUserServiceImpl.class);

    /**
     * 根据用户id获取用户对象
     *
     *
     * @param userId
     * @return
     */
    @Override
    public ServiceResult<UserDTO> findUserById(Long userId) {

        try {
            if (StringUtils.isEmpty(userId)){
                return ResultConstructor.buildServiceErrResult(ErrorConstants.RES_SERVICE_STRING,"条件错误");
            }
            UserDO user = this.userDOMapper.selectByPrimaryKey(userId);
            //使用缓存
//            redisTemplate.opsForValue().set("findUserById",user.toString());
            return getUserDTOServiceResult(user);
        } catch (Exception e) {
            //记录日志
            logger.error("findUserById error, case: " + e.getMessage());
            //返回错误信息
            return ResultConstructor.buildRunTimeErrResult(e.getMessage());
        }
    }

    @Override
    public ServiceResult<UserDTO> getUserById(Long userId) {
        UserDO user = this.userMapper.getUserDoAndUserInfoByUserId(userId);
        UserDTO userTO = null;
        //使用缓存
        if (user != null) {
            userTO = new UserDTO();
            UserInfoDTO userInfoDTO = new UserInfoDTO();
            BeanUtils.copyProperties(user.getUserInfoDO(), userInfoDTO);
            userTO.setUserInfoDTO(userInfoDTO);
            BeanUtils.copyProperties(user, userTO);
        }
        return ResultConstructor.buildSuccessResult(userTO, ErrorConstants.RES_SUCCESS, "操作成功");
    }

    /**
     * 添加用户（用户注册）
     *
     * @param userDTO
     * @return
     */
    @Override
    public ServiceResult<Integer> saveUser(UserDTO userDTO) {
        if (userDTO==null){
            return ResultConstructor.buildServiceErrResult(ErrorConstants.RES_SERVICE_STRING,"条件错误");
        }
        UserDO userDO = new UserDO();
        BeanUtils.copyProperties(userDTO,userDO);
        userDO.setCreateTime(new Date());

        try {
            //添加数据
//            int insertSelective = this.userDOMapper.insertSelective(userDO);
            Long userID = this.userDOExtMapper.saveUserDOForBackId(userDO);
//            int userID = this.userMapper.insertSelective(userDO);

            if (userID<1){
                return ResultConstructor.buildSuccessResult(userID, ErrorConstants.RES_SERVICE, "添加用户失败");
            }else{
                return ResultConstructor.buildSuccessResult(userID, ErrorConstants.RES_SUCCESS, "添加用户成功");
            }
        } catch (Exception e) {
            //记录日志
            logger.error("saveUser error, case: " + e.getMessage());
            //事务回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            //返回错误信息
            return ResultConstructor.buildRunTimeErrResult(e.getMessage());
        }
    }
    /**
     * 添加用户（用户注册,添加用户信息）
     *
     * @param userDTO
     * @return
     */
    @Override
    @Transactional
    public ServiceResult<UserDTO> saveUserToAutoProductUserInfo(UserDTO userDTO) {
        //校验条件
        if(ObjectUtils.isEmpty(userDTO)){
            return ResultConstructor.buildServiceErrResult(ErrorConstants.RES_SERVICE_STRING,"条件错误");
        }
        Date date = new Date();
        UserDO userDO = new UserDO();
        BeanUtils.copyProperties(userDTO,userDO);
        userDO.setCreateTime(date);
        Long result = this.userDOExtMapper.saveUserDOForBackId(userDO);
        if(!ObjectUtils.isEmpty(result) && result > 0){
            UserInfoDO userInfoDO = new UserInfoDO();
            userInfoDO.setUserId(userDO.getId());
            userInfoDO.setPhone(userDTO.getPhone());
            userInfoDO.setEmail(userDTO.getEmail());
            userInfoDO.setIsFreeze(new Byte("0"));
            userInfoDO.setRegisterTime(date);
            //添加成功，添加用户相信信息基本数据
            Long userInfoBackId = this.userInfoDOExtMapper.saveUserInfoBackId(userInfoDO);
            if(!ObjectUtils.isEmpty(userInfoBackId)){
                userDO.setId(result);
                //添加成功，返回成功提示
                return ResultConstructor.buildSuccessResult(userDO, ErrorConstants.RES_SUCCESS, "添加用户成功");
            }
        }
        return ResultConstructor.buildServiceErrResult(ErrorConstants.SERVER_ERROR,"用户注册失败");
    }

    /**
     * 根据邮箱查询用户
     * @param email 用户邮箱
     * @return
     */
    public ServiceResult<UserDTO> findUserByEmail(String email) {
        //测试通用mapper方法
        UserDO udo = new UserDO();
        udo.setEmail(email);
        UserDO userDO = userMapper.selectOne(udo);
        if (userDO != null) {
            UserDTO userTO = new UserDTO();
            BeanUtils.copyProperties(userDO, userTO);
            UserInfoDO userDTO = new UserInfoDO();
            userDTO.setEmail(email);
            UserInfoDO userInfoDO = userInfoMapper.selectOne(userDTO);
            UserInfoDTO userInfoTO = new UserInfoDTO();
            BeanUtils.copyProperties(userInfoDO, userInfoTO);
            userTO.setUserInfoDTO(userInfoTO);
            return ResultConstructor.buildSuccessResult(userTO, ErrorConstants.RES_SUCCESS, "操作成功");
        } else {
            return ResultConstructor.buildSuccessResult(null, ErrorConstants.RES_SUCCESS, "没有查询导数据");
        }
    }

    private ServiceResult<UserDTO> getUserDTOServiceResult(UserDO userDO) {
        if (userDO != null) {
            UserDTO userTO = new UserDTO();
            BeanUtils.copyProperties(userDO, userTO);
            return ResultConstructor.buildSuccessResult(userTO, ErrorConstants.RES_SUCCESS, "操作成功");
        } else {
            return ResultConstructor.buildSuccessResult(null, ErrorConstants.RES_SUCCESS, "没有查询导数据");
        }
    }

    /**
     * 根据手机查询用户
     * @param phone 用户手机号
     * @return
     */
    public ServiceResult<UserDTO> findUserByPhone(String phone) {
        //测试通用mapper方法
        UserDO ud = new UserDO();
        ud.setPhone(phone);
        UserDO userDO = userMapper.selectOne(ud);
        if (userDO != null) {
            UserDTO userTO = new UserDTO();
            BeanUtils.copyProperties(userDO, userTO);
            UserInfoDO userInfoDO = new UserInfoDO();
            userInfoDO.setUserId(userDO.getId());
            userInfoDO = userInfoMapper.selectOne(userInfoDO);
            UserInfoDTO userInfoTO = new UserInfoDTO();
            BeanUtils.copyProperties(userInfoDO, userInfoTO);
            userTO.setUserInfoDTO(userInfoTO);
            return ResultConstructor.buildSuccessResult(userTO, ErrorConstants.RES_SUCCESS, "操作成功");
        } else {
            return ResultConstructor.buildSuccessResult(null, ErrorConstants.RES_SUCCESS, "没有查询导数据");
        }
    }

    @Override
    @Transactional
    public ServiceResult<Long> saveUserAndSaveUserInfo(UserDTO userDTO, UserInfoDTO userInfoDTO) {
        //校验条件是否合法
        if (userDTO == null || userInfoDTO == null) {
            //返回参数错误
            return ResultConstructor.buildServiceErrResult(ErrorConstants.RES_SERVICE_STRING, "参数错误");
        }
        // 添加用户数据
        UserDO userDO = new UserDO();
        BeanUtils.copyProperties(userDTO, userDO);
        try {
            Date date = new Date();
            userDO.setCreateTime(date);
            Long result = this.userDOExtMapper.saveUserDOForBackId(userDO);
            //插入用户数据成功，开始进行添加用户信息
            if (result > 0) {
                UserInfoDO userInfoDO = new UserInfoDO();
                BeanUtils.copyProperties(userInfoDTO, userInfoDO);
                userInfoDO.setRegisterTime(date);
                userInfoDO.setUserId(userDO.getId());
                int acceptResult = this.userInfoMapper.insertSelective(userInfoDO);
                if (acceptResult > 0) {
                    return ResultConstructor.buildSuccessResult(userDO.getId());
                }
            }
            return ResultConstructor.buildSuccessResult(null);
        } catch (Exception e) {
            logger.error("添加用户错误={}", e.getMessage());
            //事务回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            //返回错误信息
            return ResultConstructor.buildRunTimeErrResult(e.getMessage());
        }
    }

    @Override
    @Transactional
    public ServiceResult<Integer> updateUserAndUserInfo(UserDTO userDTO, UserInfoDTO userInfoDTO) {
        //校验条件
        if(userDTO==null || userInfoDTO==null){
            //返回参数错误
            return ResultConstructor.buildServiceErrResult(ErrorConstants.RES_SERVICE_STRING, "参数错误");
        }
        try {
            UserDO userDO = new UserDO();
            userDO.setEmail(userDTO.getEmail());
            userDO.setPhone(userDTO.getPhone());
            userDO.setId(userDTO.getId());
            userDO.setEmailIsActive(GeneralConstants.EMAIL_ACTIVE_YES);
            Integer result = this.userMapper.updateByPrimaryKeySelective(userDO);
            if(result>0){
                //更新用户信息
                UserInfoDO userInfoDO = new UserInfoDO();
                BeanUtils.copyProperties(userInfoDTO, userInfoDO);
                userInfoDO.setEmailIsActive(GeneralConstants.EMAIL_ACTIVE_YES);
                UserInfoDOExample example = new UserInfoDOExample();
                example.createCriteria().andUserIdEqualTo(userInfoDO.getUserId());
                result += this.userInfoMapper.updateByExampleSelective(userInfoDO, example);
                if (result > 0) {
                    return ResultConstructor.buildSuccessResult(result);
                }
            }
            return ResultConstructor.buildSuccessResult(null);
        } catch (Exception e) {
            logger.error("修改用户错误={}", e.getMessage());
            //事务回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            //返回错误信息
            return ResultConstructor.buildRunTimeErrResult(e.getMessage());
        }
    }

    @Override
    public ServiceResult<Long> getUserInfoByWeiboUid(String weiboUid) {
        try {
            //通用mapper查询
            UserInfoDO userInfoDO = new UserInfoDO();
            userInfoDO.setWeiboUid(weiboUid);
            UserInfoDO one = userInfoMapper.selectOne(userInfoDO);
            if(one==null){
                return ResultConstructor.buildSuccessResult(null, ErrorConstants.RES_SUCCESS, "操作成功");
            }
            return ResultConstructor.buildSuccessResult(one.getUserId(), ErrorConstants.RES_SUCCESS, "操作成功");
        } catch (Exception e) {
            e.printStackTrace();
            return ResultConstructor.buildRunTimeErrResult(e.getMessage());
        }
    }

    @Override
    public ServiceResult<Long> getUserInfoByOpenId(String openID) {
        try {
            //通用mapper查询
            UserInfoDO userInfoDO = new UserInfoDO();
            userInfoDO.setQqOppenId(openID);
            UserInfoDO one = userInfoMapper.selectOne(userInfoDO);
            if(one==null){
                return ResultConstructor.buildSuccessResult(null, ErrorConstants.RES_SUCCESS, "操作成功");
            }
            return ResultConstructor.buildSuccessResult(one.getUserId(), ErrorConstants.RES_SUCCESS, "操作成功");
        } catch (Exception e) {
            e.printStackTrace();
            return ResultConstructor.buildRunTimeErrResult(e.getMessage());
        }
    }

    @Override
    @Transactional
    public ServiceResult<UserDTO> getUserInfoByEmailAndBindQQOrWeiBo(String userName, String webToken,String profix) {
        UserInfoDO userDTO = new UserInfoDO();
        userDTO.setEmail(userName);
        UserInfoDO userInfoDO = userInfoMapper.selectOne(userDTO);
        UserDO userDO2 = new UserDO();
        userDO2.setPhone(userName);
        UserDO userDO = userMapper.selectOne(userDO2);
        //获取qq登陆info
        //String s = RedisUtil.get(profix + webToken, null);
        String s = redisCluster.get(profix + webToken);
        UserInfoDTO userInfoDTO_redis = JSON.parseObject(s, UserInfoDTO.class);
        if(userInfoDO!=null){
            if(profix.contains("qq")){
                if(StringUtils.isEmpty(userInfoDO.getUserName())){
                    userInfoDO.setUserName(userInfoDTO_redis.getUserName());
                }
                if(StringUtils.isEmpty(userInfoDO.getQqOppenId())){
                    userInfoDO.setQqOppenId(userInfoDTO_redis.getQqOppenId());
                }
                if(StringUtils.isEmpty(userInfoDO.getAvatarUrl())){
                    userInfoDO.setAvatarUrl(userInfoDTO_redis.getAvatarUrl());
                }
                if(StringUtils.isEmpty(userInfoDO.getRegisterIp())){
                    userInfoDO.setRegisterIp(userInfoDTO_redis.getRegisterIp());
                }
            }else if(profix.contains("weibo")){
                if(StringUtils.isEmpty(userInfoDO.getUserName())){
                    userInfoDO.setUserName(userInfoDTO_redis.getUserName());
                }
                if(StringUtils.isEmpty(userInfoDO.getWeiboUid())){
                    userInfoDO.setWeiboUid(userInfoDTO_redis.getWeiboUid());
                }
                if(StringUtils.isEmpty(userInfoDO.getAvatarUrl())){
                    userInfoDO.setAvatarUrl(userInfoDTO_redis.getAvatarUrl());
                }
                if(StringUtils.isEmpty(userInfoDO.getRegisterIp())){
                    userInfoDO.setRegisterIp(userInfoDTO_redis.getRegisterIp());
                }
                if(StringUtils.isEmpty(userInfoDO.getAddress())){
                    userInfoDO.setAddress(userInfoDTO_redis.getAddress());
                }
                if(StringUtils.isEmpty(userInfoDO.getDescription())){
                    userInfoDO.setDescription(userInfoDTO_redis.getDescription());
                }
                if(StringUtils.isEmpty(userInfoDO.getSex())){
                    userInfoDO.setSex(userInfoDTO_redis.getSex());
                }
            }

            try {
                int i = userInfoMapper.updateByPrimaryKeySelective(userInfoDO);
                if (userInfoDO != null) {
                    UserInfoDTO uid = new UserInfoDTO();
                    //userinfo类型转换
                    BeanUtils.copyProperties(userInfoDO,uid);
                    //userDO类型转换
                    UserDTO userDTO2 = new UserDTO();
                    BeanUtils.copyProperties(userDO,userDTO2);
                    userDTO2.setUserInfoDTO(uid);
                    return ResultConstructor.buildSuccessResult(userDTO2);
                }

            } catch (Exception e) {
                logger.error("更新用户详情错误，绑定qq/weibo={}", e.getMessage());
                //事务回滚
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                //返回错误信息
                return ResultConstructor.buildRunTimeErrResult(e.getMessage());
            }
        }
        return null;
    }

    @Override
    @Transactional
    public ServiceResult<UserDTO> getUserInfoByPhoneAndBindQQOrWeiBo(String userName, String webToken,String profix) {
        UserInfoDO userDTO = new UserInfoDO();
        userDTO.setPhone(userName);
        UserInfoDO userInfoDO = userInfoMapper.selectOne(userDTO);
        UserDO userDO2 = new UserDO();
        userDO2.setPhone(userName);
        UserDO userDO = userMapper.selectOne(userDO2);
        //String s = RedisUtil.get(profix + webToken, null);
        String s = redisCluster.get(profix + webToken);
        UserInfoDTO userInfoDTO_redis = JSON.parseObject(s, UserInfoDTO.class);
        if(userInfoDO!=null){
            if(profix.contains("qq")){
                if(StringUtils.isEmpty(userInfoDO.getUserName())){
                    userInfoDO.setUserName(userInfoDTO_redis.getUserName());
                }
                if(StringUtils.isEmpty(userInfoDO.getQqOppenId())){
                    userInfoDO.setQqOppenId(userInfoDTO_redis.getQqOppenId());
                }
                if(StringUtils.isEmpty(userInfoDO.getAvatarUrl())){
                    userInfoDO.setAvatarUrl(userInfoDTO_redis.getAvatarUrl());
                }
                if(StringUtils.isEmpty(userInfoDO.getRegisterIp())){
                    userInfoDO.setRegisterIp(userInfoDTO_redis.getRegisterIp());
                }
            }else if(profix.contains("weibo")){
                if(StringUtils.isEmpty(userInfoDO.getUserName())){
                    userInfoDO.setUserName(userInfoDTO_redis.getUserName());
                }
                if(StringUtils.isEmpty(userInfoDO.getWeiboUid())){
                    userInfoDO.setWeiboUid(userInfoDTO_redis.getWeiboUid());
                }
                if(StringUtils.isEmpty(userInfoDO.getAvatarUrl())){
                    userInfoDO.setAvatarUrl(userInfoDTO_redis.getAvatarUrl());
                }
                if(StringUtils.isEmpty(userInfoDO.getRegisterIp())){
                    userInfoDO.setRegisterIp(userInfoDTO_redis.getRegisterIp());
                }
                if(StringUtils.isEmpty(userInfoDO.getAddress())){
                    userInfoDO.setAddress(userInfoDTO_redis.getAddress());
                }
                if(StringUtils.isEmpty(userInfoDO.getDescription())){
                    userInfoDO.setDescription(userInfoDTO_redis.getDescription());
                }
                if(StringUtils.isEmpty(userInfoDO.getSex())){
                    userInfoDO.setSex(userInfoDTO_redis.getSex());
                }
            }
            try {

                int i = userInfoMapper.updateByPrimaryKeySelective(userInfoDO);
                if (userInfoDO != null) {
                    UserInfoDTO uid = new UserInfoDTO();
                    //userinfo类型转换
                    BeanUtils.copyProperties(userInfoDO,uid);
                    //userDO类型转换
                    UserDTO userDTO2 = new UserDTO();
                    BeanUtils.copyProperties(userDO,userDTO2);
                    userDTO2.setUserInfoDTO(uid);
                    return ResultConstructor.buildSuccessResult(userDTO2);
                }

            } catch (Exception e) {
                logger.error("更新用户详情错误，绑定qq/weibo={}", e.getMessage());
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ResultConstructor.buildRunTimeErrResult(e.getMessage());
            }
        }
        return null;
    }

    @Override
    @Transactional
    public ServiceResult<UserDTO> thirdRegistAndSaveUserInfo(UserInfoDTO userDTO) {
        if (userDTO==null){
            return ResultConstructor.buildServiceErrResult(ErrorConstants.RES_SERVICE_STRING,"条件错误");
        }
        try {
                UserDO user = new UserDO();
                user.setUserName(userDTO.getUserName());
                user.setCreateTime(new Date());
                int userId = userMapper.insert(user);
                if(user.getId()!=0){
                    //生成userinfo
                    UserInfoDO userInfoDO = new UserInfoDO();
                    BeanUtils.copyProperties(userDTO,userInfoDO);
                    userInfoDO.setRegisterTime(new Date());
                    userInfoDO.setUserId(user.getId());
                    int userID = userInfoMapper.insertSelective(userInfoDO);
                    logger.info("新生成用户id为:"+user.getId());
                    if (userID<1){
                        return ResultConstructor.buildSuccessResult(userID, ErrorConstants.RES_SERVICE, "添加用户失败");
                    }else{
                        ServiceResult<UserDTO> userAndUserInfo = this.getUserById(user.getId());
                        if(userAndUserInfo.getResult()!=null){
                            return ResultConstructor.buildSuccessResult(userAndUserInfo.getResult(), ErrorConstants.RES_SUCCESS, "添加用户成功");
                        }
                        return ResultConstructor.buildSuccessResult(null, ErrorConstants.RES_SERVICE, "获取用户详情异常");
                    }
                }else {
                    return ResultConstructor.buildSuccessResult(null, ErrorConstants.RES_SERVICE, "添加用户失败");
                }

        } catch (Exception e) {
            logger.error("thirdRegistAndSaveUserInfo error, case: " + e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultConstructor.buildRunTimeErrResult(e.getMessage());
        }
    }

    @Override
    public ServiceResult<Integer> updateUserByEmial(String username,String password) {
        UserDO user = new UserDO();
        user.setPassword(password);
        Example example = new Example(UserDO.class);
        example.createCriteria().andEqualTo("email", username);
        int i = userMapper.updateByExampleSelective(user, example);
        if (i<1){
            return ResultConstructor.buildSuccessResult(i, ErrorConstants.RES_SERVICE, "更新密码失败");
        }else{
            return ResultConstructor.buildSuccessResult(i, ErrorConstants.RES_SUCCESS, "更新密码成功");
        }
    }

    @Override
    public ServiceResult<Integer> updateUserByPhone(String username,String password) {
        try {
            UserDO user = new UserDO();
            user.setPassword(password);
            Example example = new Example(UserDO.class);
            example.createCriteria().andEqualTo("phone", username);
            int i = userMapper.updateByExampleSelective(user, example);
            if (i<1){
                return ResultConstructor.buildSuccessResult(i, ErrorConstants.RES_SERVICE, "更新密码失败");
            }else{
                return ResultConstructor.buildSuccessResult(i, ErrorConstants.RES_SUCCESS, "更新密码成功");
            }
        } catch (Exception e) {
            logger.error("updateUserByPhone error, case: " + e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultConstructor.buildRunTimeErrResult(e.getMessage());
        }
    }

    @Override
    public ServiceResult<UserInfoDTO> getUserInfoDTOByUserId(Long userId) {
        try {
            UserInfoDO userInfoDO = userInfoMapper.getUserInfoDoByUserId(userId);
            UserInfoDTO userInfoTO = new UserInfoDTO();
            if(userInfoDO!=null){
                BeanUtils.copyProperties(userInfoDO, userInfoTO);
            }
            return ResultConstructor.buildSuccessResult(userInfoTO, ErrorConstants.RES_SUCCESS, "查询成功");
        } catch (BeansException e) {
            logger.error("getUserInfoDTOByUserId error, case: " + e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultConstructor.buildRunTimeErrResult(e.getMessage());
        }
    }
}
